#pragma once
#include <queue>
#include <mutex>
#include <thread>
#include <condition_variable>

void threadPoolDemoOfCpp();

typedef void (*TaskCallBack)(void *const);
typedef void (*TaskDeleter)(void *const);
// using TaskCallBack = void (*)(void *);

struct Task
{
    friend class ThreadPool;

    const TaskCallBack callBack;
    const TaskDeleter deleter;
    void *const arg;
    const bool needRun;

protected:
    Task(bool needRun) : Task(needRun, nullptr, nullptr, nullptr) {}
    Task(bool needRun, TaskCallBack callBack, void *arg, TaskDeleter deleter) : needRun(needRun), callBack(callBack), arg(arg), deleter(deleter) {}

public:
    ~Task()
    {
        if (deleter != nullptr && arg != nullptr)
            deleter(arg);
    }
};

class TaskQueue
{
public:
    TaskQueue();
    ~TaskQueue();
    void addTask(Task* task);
    Task* takeTask();
    int size();
    int empty();
    void clear();

private:
    std::queue<Task*> taskQueue;
    std::mutex queueMutex;
    std::condition_variable_any queueCondition;
};

class ThreadPool
{
public:
    ThreadPool(int min, int max);
    ~ThreadPool();
    void addTask(TaskCallBack taskCallBack);
    void addTask(TaskCallBack taskCallBack, void *arg);
    void addTask(TaskCallBack taskCallBack, void *arg, TaskDeleter deleter);

private:
    void managerProcess();
    void createWorkerProcess();
    void workerProcess();

private:
    // 线程池容纳范围：最小线程数
    const int minNum;
    // 线程池容纳范围：最大线程数
    const int maxNum;
    // 线程池状态：是否需要销毁线程池 - true 是 - fasle 否
    bool shutdown;

    // 工作中的线程数：繁忙的线程数
    int busyNum;
    // 存活的线程数：包括繁忙的和闲置的
    int liveNum;

    // 线程池锁：整个线程池操作需要保护的资源时使用的锁
    std::mutex poolMutex;
    std::condition_variable_any poolCondition;

    // 管理者线程
    std::thread managerThread;

    // 任务队列
    TaskQueue taskQueue;
};